var mslibrary = require('ms-common-library');
var ArFor = mslibrary.ArFor;
var Drawgrid = function (form, db, Callback) {
	Callback = Callback == null ? function () {} : Callback;
	var Rows = db.items;
	var loadImage = function (url, Callback) {

		var img = new Image();


		img.src = url;
		img.onload = function () {
			Callback(null, img)
		}
		img.onerror = function () {
			Callback({}, img)
		}
	}
	var drawImage = function (ctx, url, x, y, cf, dir, Callback) {

		loadImage(url, function (error, img) {
			if (error == null) {
				var size = getsize(cf);
				var height = size.height;
				var width = size.width;
				if (height * img.width / img.height < width) {
					width = height * img.width / img.height
				} else {
					height = img.height * width / img.width
				}
				if (cf.align == 2) {
					x = x + dir * (width - cf.width) / 2
				}
				ctx.drawImage(img, x, y, width, height);
			}
			Callback()
		})
	}
	var DrawRow = function (Row, Cf, left, top, dir, max_h, Callback) {
		new ArFor(Row, function () {

			Callback()
		}).forEach(function (item, next) {
			var lines = item.items;
			var cf = {};

			var _y = top + Cf.border + Cf.padding;
			var lineHeight = max_h;
			if (lines.length == 1) {
				lineHeight = max_h * 0.56;
			} else {
				lineHeight = max_h / (lines.length + 1)
			}
			new ArFor(lines, function () {
				left = left + dir * cf.width;
				next()
			}).forEach(function (connet, next) {
				cf = connet.cf;
				ctx.font = cf.FontSize + "px " + cf.font;
				ctx.fillStyle = cf.color;
				var _x = left
				if (cf.border > 0) {
					var _top = top
					ctx.moveTo(left, _top);
					ctx.lineTo(left, _top + Cf.height);
					ctx.stroke();
				}
				if (connet.text) {
					_x = _x + dir * (cf.border + cf.padding)
					if (cf.align == 2) {
						_x = _x + dir * (cf.width - connet.strWidth) / 2
					}
					_y = _y + lineHeight;
					ctx.fillText(connet.text, _x, _y);
					///_y = _y + cf.FontSize;
					next()
				} else if (connet.src) {

					_x = _x
					if (dir < 0) {
						_x = _x - cf.width;
					} else {
						_x = _x + (cf.border + cf.padding) + 3
					}
					drawImage(ctx, connet.src, _x, _y, cf, dir, function () {
						next()
					})
				} else {
					next()
				}
			});

		})
	}
	var getnewtext = function (cf, text, ctx, items) {
		var size = getsize(cf)
		for (var i = text.length; i > 0; i--) {
			ctx.font = cf.FontSize + "px " + cf.font;
			var t = text.substr(0, i);
			var obj = ctx.measureText(t);
			if (obj.width < size.width) {
				items.push({
					cf: cf,
					strWidth: obj.width,
					text: t
				});
				return getnewtext(cf, text.substr(i, text.length), ctx, items)
			}
		};
		return items
	}
	var getnewrow = function (cf, text, ctx, items) {
		for (var i = text.length; i > 0; i--) {
			var word = getnewitem(cf, text.substr(0, i), ctx);
			if (word) {
				cf.FontSize = word.FontSize;
				return getnewtext(cf, text, ctx, items)
			}
		};
		return false;
	}
	var getnewitem = function (cf, text, ctx) {
		var S = parseInt(cf.FontSize);
		var size = getsize(cf)
		for (var i = S; i > 0; i--) {
			ctx.font = i + "px " + cf.font;
			var RenderSize = ctx.measureText(text)
			if (RenderSize.width < size.width && size.height >= i && i >= cf.fontSize) {
				return {
					"text": text,
					"FontSize": i
				};
			}
		}

		if (ctx.measureText(text).width > size.width) {
			return false;
		}
	}
	var getsize = function (cf) {
		return {
			height: cf.height - cf.border * 2 - cf.padding * 2,
			width: cf.width - cf.border * 2 - cf.padding * 2
		}
	}
	var getConfig = function (cf, ob, len) {
		if (ob == null) {
			return cf;
		} else {
			len = len == null ? 1 : len;
			return {
				align: ob.align == null ? cf.align : ob.align,
				color: ob.color == null ? cf.color : ob.color,
				FontSize: ob.FontSize == null ? cf.FontSize : ob.FontSize,
				font: ob.font == null ? cf.font : ob.font,
				width: ob.width == null ? cf.width / len : ob.width,
				height: ob.height == null ? cf.height : ob.height,
				border: ob.border == null ? cf.border : ob.border,
				padding: ob.padding == null ? cf.padding : ob.padding,
				fontSize: ob.fontSize == null ? cf.fontSize : ob.fontSize
			}
		}
	}
	var Cf = {
		fontSize: 14,
		align: 1,
		color: "#000000",
		border: 0,
		font: "arial",
		FontSize: 10,
		width: 0,
		height: 0,
		padding: 0
	};
	var getabs = function (a) {
		return a < 3 ? 1 : -1;
	}
	var init = function () {
		canvas.dir = Cf.align == 1 ? "ltr" : "rtl";
		canvas.height = Cf.height;
		canvas.width = Cf.width;
		ctx.strokeStyle = "#000000";
		var linetop = 0;
		if (Cf.border) {
			ctx.lineWidth = Cf.border;
			ctx.strokeRect(Cf.border / 2, Cf.border / 2, canvas.width - Cf.border, canvas.height - Cf.border)
		}
		var getRow = function (Row, cf) {
			var max_height = 1,
				mh = 0;
			for (var k = 0; k < Row.length; k++) {
				var _cf = getConfig(cf, Row[k], Row.length);
				if (Row[k].text) {
					var r = getnewrow(_cf, Row[k].text, ctx, []);
					Row[k].items = r;
					_cf.max_height = Math.max(_cf.height, parseInt(r.length * r[0].cf.FontSize));
					max_height = Math.max(Math.max(max_height, parseInt(_cf.FontSize)), parseInt(_cf.height));
					mh = Math.max(Math.max(mh, parseInt(r.length * r[0].cf.FontSize)), max_height);
				} else {
					Row[k].cf = _cf;
					Row[k].items = [Row[k]]
					_cf.max_height = Math.max(_cf.height, 0);
					max_height = Math.max(Math.max(max_height, 0), parseInt(_cf.height));
					mh = Math.max(Math.max(mh, 0), max_height);
				}
			}
			cf.max_height = mh;
			return max_height;
		}
		var top = 0;
		new ArFor(Rows, function () {

			setTimeout(function () {
				var url = canvas.toDataURL()
				Callback(url, canvas);

			}, 30)

		}).forEach(function (obj, next) {
			var Row = obj.items;
			var cf = getConfig(Cf, obj, Rows.length);
			linetop = linetop + cf.height;
			if (cf.border > 0) {
				ctx.lineWidth = cf.border;
				ctx.moveTo(0, linetop);
				ctx.lineTo(cf.width, linetop);
				ctx.stroke();
			}
			var dir = cf.align == 1 ? 1 : -1;
			var left = (Cf.width - cf.width) / 2 + (dir == -1 ? cf.width : 0),
				max_h = getRow(Row, cf);
			DrawRow(Row, cf, left, top, dir, max_h, function () {
				top = top + max_h;
				next()
			})

		})
	}
	var canvas = form;
	var ctx = canvas.getContext("2d");
	Cf = getConfig(Cf, db);
	if (canvas.addfonts) {
		canvas.addfonts(db, function () {
			init()
		})
	} else {
		init()
	}
};

module.exports = Drawgrid;